/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Random;
import java.util.Set;

/**
 *
 * @author yan
 */
public class RandomSet<E> implements Set<E>,Iterable<E>{
    int size;
    ArrayList<E> a;
    Random r = new Random();
    
    public RandomSet() {
        this(0);
    }
    
    public RandomSet(int size) {
        a = new ArrayList<E>(this.size = size);
    }
    
    public RandomSet(Collection<? extends E> c) {
        size = (a = new ArrayList<E>(c)).size();
    }
    
    public E next() {
        if(size==0) return null;
        return a.remove(r.nextInt(size--));
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size==0;
    }

    public boolean contains(Object o) {
        return a.contains(o);
    }

    public Iterator<E> iterator() {
            Iterator<E> iterator = new Iterator<E>() {
                RandomSet<E> r = new RandomSet<E>(RandomSet.this);

                public boolean hasNext() {
                    return !r.isEmpty();
                }

                public E next() {
                    return r.next();
                }
                
                public void reset() {
                    r = new RandomSet<E>(RandomSet.this);
                }

                public void remove() {
                    throw new UnsupportedOperationException();
                }
            };
        return iterator;
    }

    public Object[] toArray() {
        return a.toArray(); 
    }

    public <T> T[] toArray(T[] a) {
        return this.a.toArray(a);
    }

    public boolean add(E e) {
        boolean b = a.add(e);
        if(b) size++;
        return b;
    }

    public boolean remove(Object o) {
        boolean b = a.remove(o);
        if(b) size--;
        return b;
    }

    public boolean containsAll(Collection<?> c) {
        return a.containsAll(c);
    }

    public boolean addAll(Collection<? extends E> c) {
        boolean b = a.addAll(c);
        size  = a.size();
        return b;
    }

    public boolean retainAll(Collection<?> c) {
        boolean b = a.retainAll(c);
        size = a.size();
        return b;
    }

    public boolean removeAll(Collection<?> c) {
        boolean b = a.removeAll(c);
        size = a.size();
        return b;
    }

    public void clear() {
        a.clear();
        size = 0;
    }
    
}
